home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 2002 November / SGI Freeware 2002 November - Disc 2.iso / dist / fw_licq.idb / usr / freeware / doc / licq / PLUGINS.HOWTO.z / PLUGINS.HOWTO
Text File  |  2002-04-08  |  4KB  |  75 lines

  1. ---------------------------------------
  2. Licq Plugins Howto v0.2
  3. Graham Roff
  4. ---------------------------------------
  5.  
  6. This document is not nearly complete and is only intended to give a
  7. bried introduction to the main ideas behind the licq plugin system.
  8. Careful perusal of the licq and qt-gui plugin source code is a good
  9. place to find out more.
  10.  
  11. 1.0  Introduction (IPC and Initialization)
  12.  
  13. Writing a plugin for licq is not too complicated.  There are two main
  14. ways for inter-system communication, signals and events.  
  15.  
  16. Signals are asynchronous and indicate some general change or occurance
  17. which the plugin might be interested in being aware of.  Signals include
  18. when your status changes, when a new message arrives, and when you log
  19. on successfully.
  20.  
  21. Events are synchronous to the extent that they are a response to
  22. something which the particular plugin started.  For example the plugin
  23. might call icqSendUrl() to send a url, and will receive a notification
  24. event in response indicating the success of failure of this call.
  25.  
  26. The arrival of a signal or event is indicated by activity on a pipe,
  27. specific to each plugin.  Each character read from the pipe can be any
  28. of PLUGIN_SIGNAL, PLUGIN_EVENT, or PLUGIN_SHUTDOWN.  A signal or event
  29. is read from the daemon simply by calling PopPluginSignal() or
  30. PopPluginEvent().
  31.  
  32. There are three main things each plugin must do:
  33.  
  34. 1.  Each plugin must include plugin.h and implement the functions
  35.     prototyped within.  These functions are described inside this header
  36.     file.  The main ones are:
  37.     LP_Init(int, char **): This function is called to initialize the
  38.     plugin, and is passed any command line arguments applicable.  The
  39.     function should return whether or not it was successful in
  40.     initializing the plugin.
  41.     LP_Main(CICQDaemon *): This function is called within its own thread
  42.     and should actually run the plugin.  It can exit by calling
  43.     LP_Exit(int) or by returning an integer return code.
  44.  
  45. 2.  Each plugin must register with the licq daemon it gets passed in
  46.     LP_Main().  This is done simply by calling CICQDaemon::Register().
  47.     This function returns the descriptor of the pipe to listen on for
  48.     notification of signals and events.  If a plugin exits without either
  49.         calling CICQDaemon::Shutdown() or receiving a shutdown signal then it
  50.         must call CICQDaemon::Unregister() to unregister itself.
  51.  
  52. 3.  Each plugin must exit properly when it receives a PLUGIN_SHUTDOWN
  53.     character on the notification pipe.  This simply involves calling
  54.     LP_Exit() or returning from LP_Main().
  55.  
  56.  
  57. 2.0  Multi-threading Issues
  58.  
  59. Licq is a fully multi-threaded program and as such there are some important
  60. issues to be dealt with when writing plugins.  First, any requests to get
  61. user information have been made thread safe (henceforth refered to as mt-safe)
  62. through a simple database type checkout system.  Given a uin, a pointer to 
  63. the relevant user is obtained by calling gUserManager.FetchUser(<uin>, <lock type>)
  64. where the <lock type> is either LOCK_R or LOCK_W depending on whether one wants
  65. read or read/write access to the user (note that many threads may have a user
  66. locked for reading at the same time, but only one thread may have a user locked
  67. for writing, so avoid doing so if possible).
  68. The same idea applies to groups: gUserManager.FetchGroup(<group id>, <lock type>).
  69.  
  70. Certain system calls should also be avoided or their mt-safe counterparts used.  These
  71. include:
  72. strerror (on some systems this call is mt-safe, use strerror_r to be sure)
  73. gethostbyname (use gethostbyname_r, see socket.cpp for an example)
  74. and any other call that uses an internal static buffer.
  75.